var data = require("./data.js");
var clickjs = require("./click.js");
var mousejs = require("./mouse.js");

let lightsjs = require("./light.js");

var define = data.define;

var cats = [];


function createCat(map, mapW, mapH, width, mapMouse) {

  if (!clickjs.canInput(map, mapW, mapH, width, mapMouse))
    return;

  var cat = {};
  cat.x = parseInt(clickjs.getX());
  cat.y = parseInt(clickjs.getY());

  cat.last_x = cat.x;
  cat.last_y = cat.y;
  cat.dir = (Math.random() * 100).toFixed() % 4;
  cat.mouse_label = 0;

  cats.push(cat);
  show_cat(cat, map, mapW, mapH, width, mapMouse);
}

function show_cat(m, map, mapW, mapH, width, mapMouse) {
  map[m.last_x][m.last_y] = 0;
  map[m.x][m.y] = m.dir + define.CU;
}

function clear_cat(m, map, mapW, mapH, width, mapMouse) {
  map[m.last_x][m.last_y] = 0;
  map[m.x][m.y] = 0;
}

var mx, my;
function find_mouse(n, map, mapW, mapH, width, mapMouse) {
  var find_width = define.Cat_Detect_Width;
  var tx = parseInt(Math.max(cats[n].x - find_width / 2, 1));
  var ty = parseInt(Math.max(cats[n].y - find_width / 2, 1));

  var ex = Math.min(tx + find_width, mapH - 2);
  var ey = Math.min(ty + find_width, mapW - 2);

  var i = 0;
  var j = 0;
  var label = -1;

  for (i = tx; i <= ex; i++) {
    for (j = ty; j < ey; j++) {
      if (mapMouse[i][j] != -1) {
        label = mapMouse[i][j];
        mx = i;
        my = j;
        if (mapMouse[i][j] == cats[n].mouse_label)
          break;
      }
    }
    if (j != ey)
      break;
  }

  if (label != -1) {
    cats[n].mouse_label = label;
    return true;
  }
  else
    return false;
}

function random_move(n, map, mapW, mapH, width, mapMouse) {
  var dir_change_prob = 40;
  var dir_change = (Math.random() * 100) > dir_change_prob;
  var i = 0;
  if (!dir_change)
    cats[n].dir += 2;//rand()%4


  cats[n].last_x = cats[n].x;
  cats[n].last_y = cats[n].y;

  for (i = 0; i < 4; i++) {
    var p = (cats[n].dir + i) % 4;
    var tx = cats[n].x + define.Dir[p][0];
    var ty = cats[n].y + define.Dir[p][1];
    if (!data.isWall(map[tx][ty]) && map[tx][ty] != define.Block) {
      cats[n].x = tx;
      cats[n].y = ty;
      cats[n].dir = p;
      break;
    }
  }
}
function move_cat(n, map, mapW, mapH, width, mapMouse) {
  mx = 0, my = 0;
  if (!find_mouse(n, map, mapW, mapH, width, mapMouse)) {
    random_move(n, map, mapW, mapH, width, mapMouse);
    return;
  }

  var tx = mx - cats[n].x;
  var ty = my - cats[n].y;

  var tdir = 0;

  if (tx == 0 && ty <= 0)
    tdir = define.Left;
  else if (tx == 0 && ty >= 0)
    tdir = define.Right;
  else if (ty == 0 && tx < 0)
    tdir = define.Up;
  else if (ty == 0 && tx >= 0)
    tdir = define.Down;
  else if (tx < 0 && ty <= 0) {
    if (data.isWall(map[cats[n].x + define.Dir[define.Left][0]][cats[n].y + define.Dir[define.Left][1]]) || map[cats[n].x + define.Dir[define.Left][0]][cats[n].y + define.Dir[define.Left][1]] == define.Block)
      tdir = define.Up;
    else
      tdir = define.Left;
  }
  else if (tx < 0 && ty > 0) {
    if (data.isWall(map[cats[n].x + define.Dir[define.Right][0]][cats[n].y + define.Dir[define.Right][1]]) || map[cats[n].x + define.Dir[define.Right][0]][cats[n].y + define.Dir[define.Right][1]] == define.Block)
      tdir = define.Up;
    else
      tdir = define.Right;
  }
  else if (tx > 0 && ty <= 0) {
    if (data.isWall(map[cats[n].x + define.Dir[define.Left][0]][cats[n].y + define.Dir[define.Left][1]]) || map[cats[n].x + define.Dir[define.Left][0]][cats[n].y + define.Dir[define.Left][1]] == define.Block)
      tdir = define.Down;
    else
      tdir = define.Left;
  }
  else if (tx > 0 && ty > 0) {
    if (data.isWall(map[cats[n].x + define.Dir[define.Right][0]][cats[n].y + define.Dir[define.Right][1]]) || map[cats[n].x + define.Dir[define.Right][0]][cats[n].y + define.Dir[define.Right][1]] == define.Block)
      tdir = define.Down;
    else
      tdir = define.Right;
  }

  cats[n].last_x = cats[n].x;
  cats[n].last_y = cats[n].y;
  cats[n].dir = tdir;

  for (var i = 0; i < 4; i++) {
    var p = (cats[n].dir + i) % 4;
    tx = cats[n].x + define.Dir[p][0];
    ty = cats[n].y + define.Dir[p][1];
    if (!data.isWall(map[tx][ty]) && map[tx][ty] != define.Block) {
      cats[n].x = tx;
      cats[n].y = ty;
      cats[n].dir = p;
      break;
    }
  }
}

function moveToLight(light, n, map, mapW, mapH, width, mapMouse)
{
  mx = light.x;
  my = light.y;
  var tx = mx - cats[n].x;
  var ty = my - cats[n].y;

  var tdir = 0;

  if (tx == 0 && ty <= 0)
    tdir = define.Left;
  else if (tx == 0 && ty >= 0)
    tdir = define.Right;
  else if (ty == 0 && tx < 0)
    tdir = define.Up;
  else if (ty == 0 && tx >= 0)
    tdir = define.Down;
  else if (tx < 0 && ty <= 0) {
    if (data.isWall(map[cats[n].x + define.Dir[define.Left][0]][cats[n].y + define.Dir[define.Left][1]]) || map[cats[n].x + define.Dir[define.Left][0]][cats[n].y + define.Dir[define.Left][1]] == define.Block)
      tdir = define.Up;
    else
      tdir = define.Left;
  }
  else if (tx < 0 && ty > 0) {
    if (data.isWall(map[cats[n].x + define.Dir[define.Right][0]][cats[n].y + define.Dir[define.Right][1]]) || map[cats[n].x + define.Dir[define.Right][0]][cats[n].y + define.Dir[define.Right][1]] == define.Block)
      tdir = define.Up;
    else
      tdir = define.Right;
  }
  else if (tx > 0 && ty <= 0) {
    if (data.isWall(map[cats[n].x + define.Dir[define.Left][0]][cats[n].y + define.Dir[define.Left][1]]) || map[cats[n].x + define.Dir[define.Left][0]][cats[n].y + define.Dir[define.Left][1]] == define.Block)
      tdir = define.Down;
    else
      tdir = define.Left;
  }
  else if (tx > 0 && ty > 0) {
    if (data.isWall(map[cats[n].x + define.Dir[define.Right][0]][cats[n].y + define.Dir[define.Right][1]]) || map[cats[n].x + define.Dir[define.Right][0]][cats[n].y + define.Dir[define.Right][1]] == define.Block)
      tdir = define.Down;
    else
      tdir = define.Right;
  }

  cats[n].last_x = cats[n].x;
  cats[n].last_y = cats[n].y;
  cats[n].dir = tdir;

  for (var i = 0; i < 4; i++) {
    var p = (cats[n].dir + i) % 4;
    tx = cats[n].x + define.Dir[p][0];
    ty = cats[n].y + define.Dir[p][1];
    if (!data.isWall(map[tx][ty]) && map[tx][ty] != define.Block) {
      cats[n].x = tx;
      cats[n].y = ty;
      cats[n].dir = p;
      break;
    }
  }
}

function eat_mouse(m, map, mapW, mapH, width, mapMouse) {
  var tx = m.x + define.Dir[m.dir][0];
  var ty = m.y + define.Dir[m.dir][1];
  if (mapMouse[tx][ty] != -1)
    return mapMouse[tx][ty];
  else
    return -1;
}

function updateOffset(i, interval) {

}

function isLong(light,cat)
{
  if(light.x==-1||light.y==-1)
    return true;
  if(Math.abs(cat.x-light.x)<=5&&Math.abs(cat.y-light.y)<=5)
    return false;
  else
    return true;
}

function updateCats(interval, map, mapW, mapH, width, mapMouse) {
  var light = lightsjs.getInfo();
  for (var i = 0; i < cats.length; i++) {
    if (interval != 0) {
      updateOffset(i, interval);
      continue;
    }
    if (!isLong(light,cats[i]))
      moveToLight(light, i, map, mapW, mapH, width, mapMouse);
    else
      move_cat(i, map, mapW, mapH, width, mapMouse);
    show_cat(cats[i], map, mapW, mapH, width, mapMouse);
    var label = eat_mouse(cats[i], map, mapW, mapH, width, mapMouse);
    if (label != -1) {
      mousejs.delete_mouse(label, map, mapW, mapH, width, mapMouse);
      console.log("eat mouse!");
    }
  }
}


function getNum() {
  return cats.length;
}

function clear() {
  cats = [];
}

function getInfo()
{
  return cats;
}

module.exports = {
  updateCats: updateCats,
  createCat: createCat,
  getNum: getNum,
  clear: clear, 
  getInfo: getInfo
}